package ie.omk.smpp.examples;

import ie.omk.smpp.Address;
import ie.omk.smpp.BadCommandIDException;
import ie.omk.smpp.Connection;
import ie.omk.smpp.message.BindResp;
import ie.omk.smpp.message.SMPPPacket;
import ie.omk.smpp.message.SubmitSM;
import ie.omk.smpp.message.SubmitSMResp;
import ie.omk.smpp.message.UnbindResp;
import ie.omk.smpp.message.tlv.Tag;
import ie.omk.smpp.util.UCS2Encoding;
import ie.omk.smpp.version.SMPPVersion;
import ie.omk.smpp.version.VersionException;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.tools.ant.BuildException;

/**
 * A synchronous transceiver example. Using sync mode for either a transceiver
 * or receiver connection is less useful than using async mode as your
 * application must now poll the connection continuously for incoming delivery
 * messages from the SMSC.
 * 
 * @see ie.omk.smpp.examples.ParseArgs ParseArgs for details on running this
 *      class.
 */
public class SyncTransceiver extends SMPPAPIExample {

	private static final Logger logger = LogManager.getLogger(SyncTransceiver.class);
    //private Log logger = LogFactory.getLog(SyncTransceiver.class);

    public SyncTransceiver() {
    }

    public static void main (String[] args){
    	new SyncTransceiver().execute();
    }
    
    private int nextRefNum = 0; 
    private synchronized int getNextRefNum () { 
    	if (nextRefNum>=65535) { //2 byte positive integer
    		nextRefNum = 0; 
    	} 
    	return ++nextRefNum; 
    }
    String receiver = "099296235";
    Address sender = new Address(0, 0, "609");
    public void execute() throws BuildException {
        try {
        	
            myConnection = new Connection(hostName, port);
            myConnection.setVersion(SMPPVersion.V34);
            myConnection.autoAckLink(true);
            myConnection.autoAckMessages(true);
            logger.info(" Connection.TRANSMITTER, systemID: " + systemID + ", password: "+password+ 
        			", systemType: "+systemType+ ",sourceTON: "+ sourceTON +", sourceNPI:" +sourceNPI+
        			", sourceAddress:" + sourceAddress);
            logger.info("Binding to the SMSC");

            BindResp resp = myConnection.bind(Connection.TRANSCEIVER, systemID, this.password, systemType,
                    this.sourceTON,this.sourceNPI, this.sourceAddress);

            if (resp.getCommandStatus() != 0) {
                logger.info("SMSC bind failed.");
                System.exit(1);
            }

            logger.info("Bind successful...submitting a message.");
            String longMessage = "hoanq: 099296235. con cò bé bé \n" + 
"hoanq: 099296235. con cò bé bé \n" +
"hoanq: 099296235. con cò bé bé \n" +
"hoanq: 099296235. con cò bé bé \n" +
"hoanq: 099296235. con cò bé bé \n" +
"hoanq: 099296235. con cò bé bé \n" +
"hoanq: 099296235. con cò bé bé \n" +
"hoanq: 099296235. con cò bé bé"; 
            //longMessage = "1                                                                                                                                 135                                                                                                                   250";
            longMessage = "ចោន​ចោ​បេ​បេ​ចោន​ចោនាលសដថ្សដលថ្ា្ឹោត្លសដថលក្ងោិ្តលកាដ្ថលកាសង្ហថកលង្ដសលាថ្ាថង្ាថ្ដសាលថ្សដាលកថ្សកល្​​​​​​​​​លា្ថលា្ថាថ្ឹ្ថលកសា្ថោា្ា្ល្ាសលដកថ្ាសលថ្ាលដថ្ឹោថ្ាល្ថលា្ថោសិថ្សលាថ្លសសា្ថាស្ថលា្ងលកាសដហ";
            // Submit a simple message
//            SubmitSM sm = (SubmitSM) smscConnection.newInstance(SMPPPacket.SUBMIT_SM);
//            sm.setDestination(new Address(0, 0, "099296235"));
//            sm.setSource(new Address(0, 0, "609"));
//            //sm.setMessageText("hoanq: 099296235. dest: ton=0, npi=0, 609 source: ton=0, npi=0", new UCS2Encoding());
//            sm.setMessageText(longMessage, new UCS2Encoding());
//            SubmitSMResp smr = (SubmitSMResp) smscConnection.sendRequest(sm);
//            logger.info("Submitted message ID: " + smr.getMessageId());
          
            UCS2Encoding  alphabet = new UCS2Encoding(); 
//            byte[] messageData = encoding.pack(encoding.encodeString(longMessage)); //encoding.encodeString(longMessage); 
//            UserData userData = new UserDataImpl(true); 
//            userData.setData(messageData); 
//            SubmitSM[] submits = UserDataUtil.createSubmits(userData.toSegments(), 
//            		new Address(0, 0, "609"), new Address(0, 0, "099296235")); 
//            for(int i = 0; i < submits.length; ++i) { 
//            	logger.info("Sending Submit Packet: " + submits[i].getMessageText()); 
//            	SubmitSMResp smr = (SubmitSMResp) smscConnection.sendRequest(submits[i]); 
//            	logger.info("Submitted message status: " + smr.getCommandStatus()); 
//            	logger.info("Submitted message ID: " + smr.getMessageId()); 
//            }
            //            
            
            int maxShortMessageLength = 134;
            int maxSegmentLength = 134;
            SubmitSM sm;
			byte[] binaryContent = alphabet.encodeString(longMessage);
			int parts = (binaryContent.length < maxShortMessageLength ? 1
					: (int) Math.ceil(((double) binaryContent.length)
							/ maxSegmentLength));
			Integer msgRefNum = new Integer(getNextRefNum());
			// SMPPRequest sm;
			if (parts == 1) {
				sm = createPacket(receiver);
				if (sm == null) {
					return;// false;
				}
				sm.setMessage(binaryContent, alphabet);
				//sendRequest(sm);
				myConnection.sendRequest(sm);
			} else {
				byte[] packet = new byte[maxSegmentLength];
				for (int i = 0; i < parts; i++) {
					sm = (SubmitSM) myConnection.newInstance(SMPPPacket.SUBMIT_SM);
					sm.setDestination(new Address(0, 0, receiver));
					sm.setSource(sender);
					sm.setOptionalParameter(Tag.SAR_TOTAL_SEGMENTS,
							new Integer(parts));
					sm.setOptionalParameter(Tag.SAR_MSG_REF_NUM, msgRefNum);
					sm.setOptionalParameter(Tag.SAR_SEGMENT_SEQNUM,
							new Integer(i + 1));
					if (i == parts - 1) {
						int pos = i * maxSegmentLength;
						int len = binaryContent.length - pos;
						byte[] finalPacket = new byte[len];
						System.arraycopy(binaryContent, pos, finalPacket, 0, len);
						sm.setMessage(finalPacket, alphabet);
					} else {
						System.arraycopy(binaryContent, i * maxSegmentLength,
								packet, 0, maxSegmentLength);
						sm.setMessage(packet, alphabet);
					}
					logger.info("Sending Submit Packet: " + sm.getMessageText()); 
					SubmitSMResp smr = (SubmitSMResp) myConnection.sendRequest(sm);
					logger.info("Submitted message status: " + smr.getCommandStatus()); 
	            	logger.info("Submitted message ID: " + smr.getMessageId());
				}
			}

            try {
                // Wait a while, see if the SMSC delivers anything to us...
                SMPPPacket p = myConnection.readNextPacket();
                logger.info("Received a packet!");
                logger.info(p.toString());

                // API should be automatically acking deliver_sm and
                // enquire_link packets...
            } catch (java.net.SocketTimeoutException x) {
                // ah well...
            }

            // Unbind.
            UnbindResp ubr = myConnection.unbind();

            if (ubr.getCommandStatus() == 0) {
                logger.info("Successfully unbound from the SMSC");
            } else {
                logger.info("There was an error unbinding.");
            }
        } catch (Exception x) {
            logger.info("An exception occurred.");
            x.printStackTrace(System.err);
        }
    }

	private SubmitSM createPacket(String receiver2) throws VersionException, BadCommandIDException {
		SubmitSM sm = (SubmitSM) myConnection.newInstance(SMPPPacket.SUBMIT_SM);
        sm.setDestination(new Address(0, 0, "099296235"));
        sm.setSource(new Address(0, 0, "609"));
        return sm;
	}
}

